package com.gxlu.ms.base.processflow;

import java.util.ArrayList;
import java.util.List;

import com.gxlu.ms.base.module.context.Context;
import com.gxlu.ms.base.module.handler.IHandler;
import com.gxlu.ms.base.module.profile.JProfile;
import com.gxlu.ms.base.result.FinalResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * ProcessExecutor 流程执行器
 * @author lhc
 * @date 2018/03/16
 *
 */
public class ProcessExecutor {

    private static final Logger logger = LoggerFactory.getLogger(ProcessExecutor.class);

    private List<IHandler> handlers = new ArrayList<>(16);

    public List<IHandler> getHandlers() {
        return handlers;
    }

    public ProcessExecutor setHandlers(List<IHandler> handlers) {
        this.handlers = handlers;
        return this ;
    }

    public  ProcessExecutor setHandler(IHandler handler){
        if( !this.handlers.contains(handler)){
            this.handlers.add(handler) ;
        }
        return this ;
    }

    public FinalResult execute(Context context){
        if(handlers.isEmpty()){
            logger.warn(">>>>[ProcessExecutor][execute] handlers.isEmpty,please set handlers!");
            return FinalResult.success();
        }
        FinalResult result = null ;
        for(IHandler handler:handlers){
           JProfile.enter(handler.getClass()+"#execute");
           try{
               result = (FinalResult)handler.execute(context) ;
               if(result==null){
                   String msg = String.format("[ProcessExecutor][execute] execute result is null,handler:%s,context:%s",handler,context);
                   logger.error(">>>>[ProcessExecutor][execute] handler:"+handler+",execute result is null");
                   result = FinalResult.of(false,0,msg) ;
                   break;
               }
               // false 直接返回
               if(!result.getStatus()){
                   break ;
               }
           }catch (Throwable e){
               String msg = String.format("[ProcessExecutor][execute] handler:%s,context:%s",handler,context);
               logger.error(msg ,e);
               result = FinalResult.of(false,500,"handler:"+handler.getClass().getSimpleName()+"执行错误") ;
               break ;
           }finally {
              JProfile.release();
           }
        }
        return  result ;
    }
}
